package org.example.rabbitmq.consumer;

import org.example.rabbitmq.consumer.mq.MyMessageConsumer;
import org.example.rabbitmq.consumer.mq.RabbitMqManager;
import org.example.rabbitmq.consumer.notify.DynamicQueueCreatedConsumer;
import org.example.rabbitmq.consumer.notify.Names;
import org.example.rabbitmq.consumer.rate.NopRateLimiter;
import org.example.rabbitmq.consumer.rate.RateLimiter;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.UUID;

@SpringBootApplication
public class DynamicQueueConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(DynamicQueueConsumerApplication.class, args);
    }

    @Bean
    public RateLimiter rateLimiter() {
        return new NopRateLimiter();
    }

    @Bean
    public FanoutExchange notifyExchange() {
        return new FanoutExchange(Names.NOTIFY_EXCHANGE_NAME, true, false);
    }

    @Bean
    public Queue localNotifyQueue(Environment environment) {
        String queueName = environment.getProperty("mq.notify.queue-name");
        if (StringUtils.isEmpty(queueName)) {
            try {
                queueName = "queue-created-notify-" + InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                queueName = "queue-created-notify-" + UUID.randomUUID().toString();
            }
        }
        return new Queue(queueName, true, false, false);
    }

    @Bean
    public Binding localNotifyQueueBinding(Environment environment) {
        return BindingBuilder.bind(localNotifyQueue(environment)).to(notifyExchange());
    }

    @Bean
    public DynamicQueueCreatedConsumer dynamicQueueCreatedConsumer() {
        return new DynamicQueueCreatedConsumer();
    }

    @Bean
    public SimpleMessageListenerContainer localNotifyQueueContainer(Environment environment, ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueues(localNotifyQueue(environment));
        container.setMessageListener(dynamicQueueCreatedConsumer());
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return container;
    }

    @Bean
    public MyMessageConsumer myMessageConsumer() {
        return new MyMessageConsumer();
    }

    @Bean
    public RabbitMqManager rabbitMqManager() {
        return new RabbitMqManager(myMessageConsumer());
    }
}